/**
* Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.wsinfra.deployment.axis.wsr.proxy;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;

import org.apache.xmlbeans.XmlCursor;

import cgl.narada.wsinfra.exception.DeploymentException;
import cgl.narada.wsinfra.exception.MessageFlowException;
import cgl.narada.wsinfra.exception.ProcessingException;
import cgl.narada.wsinfra.schemas.addressing.ActionDocument;
import cgl.narada.wsinfra.schemas.addressing.EndpointReferenceType;
import cgl.narada.wsinfra.schemas.addressing.FromDocument;
import cgl.narada.wsinfra.schemas.addressing.RelatesToDocument;
import cgl.narada.wsinfra.schemas.soap.EnvelopeDocument;
import cgl.narada.wsinfra.util.SoapEnvelopeConversion;
import cgl.narada.wsinfra.util.SoapMessageAlteration;
import cgl.narada.wsinfra.wsa.WsaEnvelopeCreator;
import cgl.narada.wsinfra.wsa.WsaEprCreator;
import cgl.narada.wsinfra.wsa.WsaProcessingFactory;
import cgl.narada.wsinfra.wsr.WsrActions;
import cgl.narada.wsinfra.wsr.WsrQNames;

/**
 * @author Damodar Yemme 
 * $Date: 2005/04/22 21:58:59 
 * $Revision: 1.2 $ 
 * 
 * This acts as Application at WsrSource Proxy Web Service. It will initiates
 * all requests for Wsr Source.
 */
public class WsrSourceProxyClient {
    private WsaEprCreator wsaEprCreator;

    private WsaEnvelopeCreator wsaEnvelopeCreator;

    private SoapEnvelopeConversion soapEnvelopeConversion;

    private SoapMessageAlteration soapMessageAlteration;

    private WsrSourceProxyClientService wsrSourceClientService;

    private WsrActions wsrActions;

    private int tracker;

    private String moduleName = "WsrSourceProxyClient :";

    private static String sinkAddress;

    private static String sourceAddress;
    
    /**
     * This constructor will initiates all services at Application or Client to
     * creates SOAPMessage requests for Wsr Source Node by taking database 
     * config file as constructor parameter
     *   
     * @throws DeploymentException
     */
    public WsrSourceProxyClient() throws DeploymentException {
        sinkAddress = WsrProxyServicesFactory.getSinkAddress();
        sourceAddress = WsrProxyServicesFactory.getSourceAddress();
        wsrActions = WsrActions.getInstance();
        wsaEprCreator = WsaProcessingFactory.getWsaEprCreator();
        wsaEnvelopeCreator = WsaProcessingFactory.getWsaEnvelopeCreator();
        wsrSourceClientService = new WsrSourceProxyClientService();
        soapEnvelopeConversion = SoapEnvelopeConversion.getInstance();
        soapMessageAlteration = SoapMessageAlteration.getInstance();
    }
   
   
    /**
     * This method will send SOAPMessage to Network
     * @param soapMessage
     * @throws DeploymentException
     * @throws MessageFlowException
     * @throws ProcessingException
     */
    public void sendSOAPMessage(SOAPMessage soapMessage)
            throws DeploymentException, MessageFlowException,
            ProcessingException {
        wsrSourceClientService.enrouteToNetwork(soapMessage);
    }
    /**
     * This method will create SOAPMessage based on given paramters.
     * @param source
     * @param sink
     * @param groupId
     * @param replyPattern
     * @param replyTo
     * @param lastMessage
     * @return SOAPMessage
     */
    public SOAPMessage createSOAPMessage(String source, String sink,
            String groupId, String replyPattern, String replyTo,
            String lastMessage) {

        EndpointReferenceType sourceEpr = wsaEprCreator.createEpr(source);
        
        EndpointReferenceType sinkEpr = wsaEprCreator.createEpr(sink);
        

        FromDocument from = FromDocument.Factory.newInstance();
        from.setFrom(sourceEpr);
       
        ActionDocument action = ActionDocument.Factory.newInstance();
        action.addNewAction().setStringValue(wsrActions.getProcessRequest());
        RelatesToDocument relatesTo = null;

        EnvelopeDocument envelopeDocument = wsaEnvelopeCreator
                .createSoapEnvelope(sinkEpr, from, action, relatesTo);
        QName qname = new QName("http://www.naradabrokering.org",
                "Application-Content");
        XmlCursor bodyCursor = envelopeDocument.getEnvelope().getBody()
                .newCursor();
        tracker++;
        String value = "Tracker :" + tracker;
        bodyCursor.toNextToken();
        bodyCursor.insertElementWithText(qname, value);
        bodyCursor.dispose();
        System.out.println(envelopeDocument.toString());

        if (groupId != null) {
            QName qName = WsrQNames.getInstance().getGroupId();
            boolean added = soapMessageAlteration.addToSoapHeader(
                    envelopeDocument, qName, groupId);
           
        }
        if (replyPattern != null) {
            QName qName = WsrQNames.getInstance().getRPattern();
            boolean added = soapMessageAlteration.addToSoapHeader(
                    envelopeDocument, qName, replyPattern);
           
        }
        if (replyTo != null) {
            QName qName = WsrQNames.getInstance().getReplyTo();
            boolean added = soapMessageAlteration.addToSoapHeader(
                    envelopeDocument, qName, replyTo);
           
        }
        if (lastMessage != null) {
            QName qName = WsrQNames.getInstance().getLastMessage();
            boolean added = soapMessageAlteration.addToSoapHeader(
                    envelopeDocument, qName, lastMessage);
            
        }

        SOAPMessage soapMessage = null;
        try {
            soapMessage = soapEnvelopeConversion
                    .getSOAPMessage(envelopeDocument);
        } catch (ProcessingException ex) {
            String errorReport ="Problems converting to javax.xml.SOAPMessage\n"
                    + ex.toString();
            System.out.println(errorReport);
        }
        return soapMessage;

    }
     /**
     * Main method for this application and user can initiates all request from
     * this method from command prompt.
     * @param args
     */
    public static void main(String[] args) {
        Properties props = new Properties();
        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tok;
        String cmd;

        try {

            WsrSourceProxyClient endpoint = new WsrSourceProxyClient();
            System.out
                    .println("Wsr Source client running : type 'h' for help ");
            while (true) {
                cmd = r.readLine();

                if(cmd.startsWith("h")) {                	  
                	  System.out.println("Response-Reply Pattern & Optional " +
                	  		"groupId & " +"Last Message =false -> 1 [groupId]");
                	  System.out.println("Response-Reply Pattern & Optional " +
                	  		"groupId & " + "Last Message =true -> 2 [groupId]");
                	  System.out.println("Callback-Reply Pattern & Optional " +
                	  		"groupId & " +"Last Message = false-> 3 [groupId]");
                	  System.out.println("Callback-Reply Pattern & Optional " +
                	  		"groupId & " +"Last Message = true-> 4 [groupId]");
                	  System.out.println("Callback-Reply Pattern & Reply-To & "+
                	  	"groupId & Last Message=false -> 5 [replyto][groupid]");
                	  System.out.println("Callback-Reply Pattern & Reply-To & "+
                	  		"Optinal groupId &" 
                	  		+" Last Message = true -> 6 [replyto][groupid]");
                	System.out.println("Poll-Reply Pattern & Optional groupId &" 
                	  		+" Last Message = false-> 7 [groupId]");
                	System.out.println("Poll-Reply Pattern & Optional groupId &" 
                	  		+" Last Message = true-> 8 [groupId]");
                	  
                	}	
               
                if (cmd.startsWith("1")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s1" */
                    
                    String groupId = null;
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
													"Response", null, "false");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                if (cmd.startsWith("2")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s2" */                    
                    String groupId = null;
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
													"Response", null, "true");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                if (cmd.startsWith("3")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s3" */
                    
                    String groupId = null;
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
													"Callback", null, "false");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                if (cmd.startsWith("4")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s4" */
                    
                    String groupId = null;
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
													"Callback", null, "true");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                if (cmd.startsWith("5")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s5" */
                    
                    String groupId = null;
                    String replyTo = null;
                    if (tok.hasMoreTokens()) {
                        replyTo = tok.nextToken();
                    }
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint
                            .createSOAPMessage(sourceAddress, sinkAddress, 
                            		groupId, "Callback", replyTo, "false");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                if (cmd.startsWith("6")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s6" */
                    
                    String groupId = null;
                    String replyTo = null;
                    if (tok.hasMoreTokens()) {
                        replyTo = tok.nextToken();
                    }
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
												"Callback", replyTo, "true");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                if (cmd.startsWith("7")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s7" */
                    
                    String groupId = null;
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
														"Poll", null, "false");
                    endpoint.sendSOAPMessage(soapMessage);
                }

                if (cmd.startsWith("8")) {
                    tok = new StringTokenizer(cmd, " ");
                    tok.nextToken(); /* skipping the token "s8" */                    
                    String groupId = null;
                    if (tok.hasMoreTokens()) {
                        groupId = tok.nextToken();
                    }
                    SOAPMessage soapMessage = endpoint.createSOAPMessage(
                            sourceAddress, sinkAddress, groupId, 
														"Poll", null, "true");
                    endpoint.sendSOAPMessage(soapMessage);
                }
                

            } /* end while(true) */

        } catch (Exception ioe) {
            ioe.printStackTrace();
        } /* end try-catch */
    }/* end main() */
}
